Imports System.Runtime.InteropServices
Imports System.Text.Encoding

Namespace Protocol

    Public Module mProtocol

        'holds the client version string, this can be any string of 31 characters or less and should be specific
        'that is, if you have modified the client to be inline with modification made to your server, then the
        'client version string should be modified to one unique to your client/server
        Public Const sClientVersion As String = "MIREVOTESTCLIENT 0.2.0.6"

#Region "=========   CONST ========="

        Public Const InactiveTimeoutSecs As Integer = 180
        Private Const DefaultPacketLen As Integer = 21

        Public Structure PACKETTYPE
            <MarshalAs(UnmanagedType.U2)> Dim UINT16_TYPE As UInt16
        End Structure

        Private Const sProto As String = "MEVO" 'use for quick comparison, no need for ascii.getstring
        Public bProto() As Byte = {77, 69, 86, 79} '"MEVO"
        Public Const bProtoStartHeader As Byte = 1

        Public Const MAX_USERNAME_LEN As Integer = 25
        Public Const MAX_CHARNAME_LEN As Integer = 25
        Public Const MAX_PASSWORD_LEN As Integer = 25
        Public Const MAX_EMAIL_LEN As Integer = 128
        Public Const MAX_ITEMNAME_LEN As Integer = 32
        Public Const MAX_CHATMSG_LEN As Integer = 256
        Public Const MAX_MONNAME_LEN As Integer = 24
        Public Const MAX_MAPFILE_LEN As Integer = 16
        Public Const MAX_MAPNAME_LEN As Integer = 24
        Public Const MAX_SAY_LEN As Integer = 2048
        Public Const MAX_FUNC_LEN As Integer = 128
        Public Const MAX_SKILLDESC_LEN As Integer = 128
        Public Const MAX_HOSTNAME_LEN As Integer = 64
        Public Const MAX_ERROR_LEN As Integer = 4096

        Public Const MD5PASS_LEN As Integer = 25

        Public Const MIN_USERNAME_LEN As Integer = 6
        Public Const MIN_PASSWORD_LEN As Integer = 6
        Public Const MIN_CHARNAME_LEN As Integer = 3

        Public Const VALID_USERNAME_CHARS As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
        Public Const VALID_PASSWORD_CHARS As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
        Public Const VALID_CHARNAME_CHARS As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_"
        Public Const VALID_EMAIL_CHARS As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!#$%*/?|^{}`~&'+-=_@." & Chr(34)
        Public Const VALID_CHAT_CHARS As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!#$%*/?|^{}`~&'+-=_@.():<> " & Chr(34)

        Public Const MAX_CHARS As Integer = 2 'note changing this value will not allow more characters, it requires considerably more coding (mostly on the client side)

        Public Const DefaultUsername As String = ""

#End Region



        'Used to differentiate between Packet Types
#Region "=========  PACKET TYPES  ========="

        Public Enum GenericPacketType As UInt16
            ClientVersion = 32
            ServerState = 33
            SessionID = 34
            PingTest = 35
            ClientError = 36
        End Enum

        Public Enum LoginPacketType As UInt16
            TryLogin = 52
            TryNewLogin = 53
            CharList = 54
            TryNewChar = 55
            TryDelChar = 56
            TrySelectChar = 57
            TryMagicPacket = 58
        End Enum

        Public Enum GamePacketType As UInt16
            SwitchServer = 60

            PlayerUpdate = 72
            CharacterAddUpdate = 73
            CharacterMoveUpdate = 74
            CharacterRemoveUpdate = 75
            ChatMsg = 76
            PlayerMove = 77
            AddToInventory = 78
            EquipItem = 79
            ChangeItemLocation = 80
            MobAddUpdate = 81
            MobMoveUpdate = 82
            MobRemoveUpdate = 83
            PlayerHit = 84
            CharacterHit = 85
            MobHit = 86
            Magic = 87
            PlayerStatsUpdate = 88
            CharacterShapeUpdate = 89
            CharacterDie = 90
            LoadNewMap = 91
            Resync = 92
            EnterGame = 93
            FloorItemAddUpdate = 94
            FloorItemRemoveUpdate = 95
            FloorItemPickup = 96
            DropItem = 97
            DisconnectClient = 98
            MobChatMsg = 99
            SplitStack = 100
            JoinStacks = 101
            RemoveItem = 102
            UseItem = 103
            NPCCall = 104
            NPCAddUpdate = 105
            NPCShopItemsBeginUpdate = 106
            NPCShopItemsAdd = 107
            NPCShopItemsEndUpdate = 108
            NPCSay = 109
            NPCShopBuy = 110
            NPCShopLoadItems = 111
            NPCShopBeginAllowList = 112
            NPCShopAllow = 113
            NPCShopEndAllowList = 114
            NPCShopSell = 115
            SetCurrency = 116
            SetExp = 117

            AddPlayerSkill = 118 'Notify = Client Learn, Enquiry = List Req & Reset, Answer = List Item, NegAck = Stop List
            SetSkillMapping = 119 '  "  "  "  "  "   

            FormGroup = 120
            AddToGrp = 121
            RemoveFrmGrp = 122

            UpdatePlayerWeights = 123

        End Enum

        Public Enum PacketOpCode As Byte
            Enquiry = 5
            Answer = 2
            Acknowledge = 6
            NegAcknowledge = 21
            'custom op codes
            Notify = 32

            Custom2 = 33
            Custom3 = 34
            Custom4 = 35
            Custom5 = 36
            Custom6 = 37
            Custom7 = 38
            Custom8 = 39
            Custom9 = 40
            Custom10 = 41
            Custom11 = 42
            Custom12 = 43
            Custom13 = 44
            Custom14 = 45
            Custom15 = 46
            Custom16 = 47
            Custom17 = 48
            Custom18 = 49
            Custom19 = 50
            Custom20 = 51
            Custom21 = 52
            Custom22 = 53
            Custom23 = 54
            Custom24 = 55
            Custom25 = 56
            Custom26 = 57
            Custom27 = 58
            Custom28 = 59
            Custom29 = 60
            Custom30 = 61
            Custom31 = 62
            Custom32 = 63
        End Enum

#End Region


#Region "=========  GENERIC  ========="

        <StructLayout(LayoutKind.Sequential)> _
        Public Structure Packet
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_USERNAME_LEN)> Dim Username As String
            <MarshalAs(UnmanagedType.U2)> Dim PacketType As UInt16
            <MarshalAs(UnmanagedType.U1)> Dim PacketOpCode As PacketOpCode
        End Structure

        <StructLayout(LayoutKind.Sequential, Pack:=1)> _
        Public Structure RawPacket
            <MarshalAs(UnmanagedType.ByValArray, ArraySubType:=UnmanagedType.U1, SizeConst:=4)> Dim Proto() As Byte
            <MarshalAs(UnmanagedType.U1)> Dim StartHeaderByte As Byte
            <MarshalAs(UnmanagedType.U1)> Dim HeaderUsername As ProtoHeaders
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_USERNAME_LEN)> Dim Username As String
            <MarshalAs(UnmanagedType.U1)> Dim HeaderPacketType As ProtoHeaders
            Dim PacketType As PACKETTYPE
            <MarshalAs(UnmanagedType.U1)> Dim HeaderPacketOpCode As ProtoHeaders
            <MarshalAs(UnmanagedType.U1)> Dim PacketOpCode As PacketOpCode
            <MarshalAs(UnmanagedType.U1)> Dim HeaderPayload As ProtoHeaders
            <MarshalAs(UnmanagedType.I2)> Dim PayloadLength As UInt16
        End Structure

        Public Enum ProtoHeaders As Byte

            'headers must appear in the order listed to ensure correct functionality!
            'the only optional header parameter is the encrypted payload

            Username = 32 '4 byte
            PacketType = 34 '1 byte
            PacketOpCode = 35 '1 byte
            Payload = 36 'followed by 2 byte UInt16 indicating encrypted payload length, then the encrypted payload

            EndOfTransmission = 4 'indicates that the packet was correctly processed by marking the last byte

        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure GenericMessage
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Dim MESSAGE As String
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ClientErrorText
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_ERROR_LEN)> Dim STR As String
        End Structure

#End Region
#Region "=========  AUTH  ========="

        '<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        'Public Structure ClientVersion
        '    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim CLIENTVER As String
        'End Structure

        '<StructLayout(LayoutKind.Sequential)> _
        'Public Structure SessionID
        '    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim SESSIONID() As Byte
        'End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure UserLogin
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_USERNAME_LEN)> Dim STR_USERNAME As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim STR_CLIENTVER As String
        End Structure



        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure NewUserLogin
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_USERNAME_LEN)> Dim STR_USERNAME As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MD5PASS_LEN)> Dim STR_PASSMD5 As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_EMAIL_LEN)> Dim STR_EMAIL As String
        End Structure

#End Region
#Region "=========  SELECT CHARACTER  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure SelCharList
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SELECTED As Byte
            Dim CHAR_1 As SelCharInfo
            Dim CHAR_2 As SelCharInfo
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure SelCharInfo
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim STR_NAME As String
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_JOB As CharacterJobs
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SEX As Gender
            <MarshalAs(UnmanagedType.I2)> Dim INT2_LEVEL As UInt16
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CreateCharInfo
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim STR_NAME As String
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_JOB As CharacterJobs
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SEX As Gender
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure DelCharRequest
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MD5PASS_LEN)> Dim STR_PASSMD5 As String
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure SelectCharRequest
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SELECTED As Byte
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
        End Structure

#End Region
#Region "=========  GAME GENERIC  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PositionInfo
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=15)> Dim STR_MAP As String
            <MarshalAs(UnmanagedType.I2)> Dim INT2_X As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_Y As Int16
        End Structure

        Public Enum CharacterJobs As Byte
            Warrior = 0
            Sorcerer = 1
            Taoist = 2
            Assassin = 3
        End Enum

        Public Enum Gender As Byte
            Male = 0
            Female = 1
        End Enum

        Public Enum Direction As Byte
            N = 0
            NE = 1
            E = 2
            SE = 3
            S = 4
            SW = 5
            W = 6
            NW = 7
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure Vitals
            <MarshalAs(UnmanagedType.I2)> Dim HP As Int16
            <MarshalAs(UnmanagedType.I2)> Dim MP As Int16
            <MarshalAs(UnmanagedType.I2)> Dim MAXHP As Int16
            <MarshalAs(UnmanagedType.I2)> Dim MAXMP As Int16
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShapeInfo
            <MarshalAs(UnmanagedType.I4)> Dim INT_ARMORSHAPE As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_ARMORCOL As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_HAIRSHAPE As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_HEADSHAPE As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_HAIRCOL As Integer
            <MarshalAs(UnmanagedType.Bool)> Dim BOOL_HEADISHELM As Boolean
            <MarshalAs(UnmanagedType.I4)> Dim INT_WEAPONSHAPE As Integer
            <MarshalAs(UnmanagedType.Bool)> Dim BOOL_HASLIGHT As Boolean
        End Structure

#End Region
#Region "=========  PLAYER  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ExpInfo
            <MarshalAs(UnmanagedType.I2)> Dim INT2_LEVEL As Int16
            <MarshalAs(UnmanagedType.I8)> Dim INT8_EXP As Long
            <MarshalAs(UnmanagedType.I8)> Dim INT8_TOTALEXP As Long
        End Structure

        Public Enum CurrencyType As Byte
            Gold = 0
            GameGold = 1
            FamePoints = 2
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CurrencyInfo
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As CurrencyType
            <MarshalAs(UnmanagedType.I8)> Dim INT8_AMMOUNT As Long
            <MarshalAs(UnmanagedType.I8)> Dim INT8_TOTAL As Long
        End Structure

        Public Enum PlayerType As Byte
            Normal = 0
            HighRank = 1
            GM = 2
            DEV = 3
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerInfo
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim STR_NAME As String
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_GENDER As Gender
            <MarshalAs(UnmanagedType.U1)> Dim TYPE As PlayerType
            Dim ShapeInfo As ShapeInfo
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure StartInfo
            Dim LoadMapInfo As LoadMapInfo
            Dim ShapeInfo As ShapeInfo
            Dim VitalPoints As Vitals
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerPositionInfo
            <MarshalAs(UnmanagedType.I2)> Dim INT2_X As Int16
            <MarshalAs(UnmanagedType.I4)> Dim INT2_Y As Integer
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_DIRECTION As Direction
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_ANIM As HUMAnimation
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure LoadMapInfo
            Dim Posinfo As PositionInfo
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_MAPNAME_LEN)> Dim STR_MAPNAME As String
            <MarshalAs(UnmanagedType.U2)> Dim Fmmap_Index As UInt16
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure SwitchServer
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_HOSTNAME_LEN)> Dim STR_HOSTNAME As String
            <MarshalAs(UnmanagedType.I4)> Dim INT_PORT As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerWeights
            <MarshalAs(UnmanagedType.I4)> Dim INT4_BAGWEIGHT As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT4_WEARWEIGHT As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT4_HANDWEIGHT As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerWeightDesc
            <MarshalAs(UnmanagedType.I8)> Dim ID_CHARACTER As Long
            Dim Weights As PlayerWeights
        End Structure

#End Region
#Region "=========  MOBS  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobPositionInfo
            <MarshalAs(UnmanagedType.I2)> Dim INT2_X As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_Y As Int16
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_DIRECTION As Direction
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_ANIM As MobAnimation
            <MarshalAs(UnmanagedType.I8)> Dim INT8_SPEED As Int64
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobStats
            <MarshalAs(UnmanagedType.I2)> Dim Level As Int16
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_MONNAME_LEN)> Dim Name As String
            <MarshalAs(UnmanagedType.I2)> Dim Avatar As Int16
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobAddInfo
            <MarshalAs(UnmanagedType.I8)> Dim ServerMobID As Int64
            <MarshalAs(UnmanagedType.I4)> Dim INT2_SHAPE As Integer
            Dim Positioninfo As MobPositionInfo
            Dim VitalPoints As Vitals
            Dim Info As MobStats
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobUpdateInfo
            <MarshalAs(UnmanagedType.I8)> Dim ServerMobID As Int64
            <MarshalAs(UnmanagedType.I4)> Dim INT2_SHAPE As Integer
            Dim Positioninfo As MobPositionInfo
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobRemoveInfo
            <MarshalAs(UnmanagedType.I8)> Dim ServerMobID As Int64
        End Structure

        Public Enum MobAnimation As Byte
            Standing = 0
            Walking = 1
            MeleeAttack = 2
            TakingHit = 3
            Die = 4
            Bones = 11
        End Enum


#End Region
#Region "=========  CHARACTERS  ========="

        Public Enum CharacterUpdateType As Byte
            Add = 0
            Move = 1
            Remove = 2
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CharacterAddInfo
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
            Dim playerinfo As PlayerInfo
            Dim Positioninfo As PlayerPositionInfo
            Dim VitalPoints As Vitals
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CharacterMoveInfo
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
            Dim Positioninfo As PlayerPositionInfo
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CharacterID
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CharacterShape
            <MarshalAs(UnmanagedType.I4)> Dim ID_CHARACTER As Integer
            Dim info As ShapeInfo
        End Structure



#End Region
#Region " =========  COMBAT  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobHitInfo
            <MarshalAs(UnmanagedType.I8)> Dim ServerMobID As Int64
            Dim VitalPoints As Vitals
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CharacterHitInfo
            <MarshalAs(UnmanagedType.I4)> Dim CharacterID As Integer
            Dim VitalPoints As Vitals
            <MarshalAs(UnmanagedType.Bool)> Dim IgnoreMiss As Boolean
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerHitInfo
            Dim VitalPoints As Vitals
            <MarshalAs(UnmanagedType.Bool)> Dim IgnoreMiss As Boolean
        End Structure

        Public Enum AttackModes As Byte
            Peace = 0
            AttackAll = 1
        End Enum

        Public Enum TargetType As Byte
            Mob = 0
            Player = 1
            Pet = 2
            Coords = 3
        End Enum

#End Region
#Region "=========  MAGIC ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MagicCast
            Dim magiccode As Magics
            Dim dir As Direction
            Dim target_type As TargetType
            <MarshalAs(UnmanagedType.I8)> Dim targetparam1 As Int64
            <MarshalAs(UnmanagedType.I8)> Dim targetparam2 As Int64
            <MarshalAs(UnmanagedType.I8)> Dim CharID As Int64
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure AddMagic
            Dim magiccode As Magics
            Dim dir As Direction
            <MarshalAs(UnmanagedType.I2)> Dim startx As Int16
            <MarshalAs(UnmanagedType.I2)> Dim starty As Int16
            <MarshalAs(UnmanagedType.I2)> Dim destx As Int16
            <MarshalAs(UnmanagedType.I2)> Dim desty As Int16
            <MarshalAs(UnmanagedType.I8)> Dim CharID As Int64
        End Structure

        Public Enum Element
            Fire = 0
            Ice = 1
            Lightning = 2
            Wind = 3
            Holy = 4
            Dark = 5
            Phantom = 6
        End Enum

        Public Enum Magics
            AdamantineFireballCast = 0
            AdamantineFireballProjectile = 1
            AdamantineFireballHit = 2
            MeteorShowerCast = 3
            MeteorShowerProjectile = 4
            Teleport = 5
            LevelUp = 6
            Slaying = 7
            HealingCast = 8
            HealingEffect = 9
            FireballCast = 10
            FireballProjectile = 11
            FireballHit = 12
        End Enum

        Public Enum MagicAnimIndex

            Teleport = 111
            AdamantineFireballCast = 1561
            AdamantineFireballProjectile = 1641
            AdamantineFireballHit = 1801
            LevelUp1 = 3801
            LevelUp2 = 3851
            Slaying = 1351
            HealingCast = 661
            HealingEffect = 611
            FireballCast = 1561
            FireballProjectile = 421
            FireballHit = 581

        End Enum

        Public Enum MagicAnimCount

            Teleport = 10
            AdamantineFireballCast = 9
            AdamantineFireballProjectile = 6
            AdamantineFireballHit = 10
            LevelUp1 = 24
            LevelUp2 = 28
            Slaying = 6
            HealingCast = 10
            HealingEffect = 10
            FireballProjectile = 5
            FireballHit = 10

        End Enum

        Public Enum MagicAnimSpeed

            AdamantineFireballCast = 722000
            AdamantineFireballProjectile = 75000
            AdamantineFireballHit = 750000
            Teleport = 750000
            LevelUp = 750000
            Slaying = 750000
            HealingCast = 750000
            HealingEffect = 750000
            FireballProjectile = 75000
            FireballHit = 750000

        End Enum

        Public Enum MagicAnimSpeedXY

            AdamantineFireballProjectile = -18
            FireballProjectile = -12

        End Enum

#End Region
#Region "=========  ITEMS  ========="

        Public Enum ItemType As Byte
            MArmor = 0
            FArmor = 1
            Helmet = 2
            Necklace = 3
            Ring = 4
            Bracer = 5
            Shoes = 6
            Weapon = 7
            Torch = 8
            Trinket = 9
            Talisman = 10
            HorseArmor = 11
            Liquor = 12
            Potion = 13
            Scroll = 14
            WarriorBook = 15
            TaoistBook = 16
            SorcererBook = 17
            Meat = 18
        End Enum

        Public Enum ItemClass As Byte
            Loot = 0
            Normal = 1
            Superior = 2
            Rare = 3
        End Enum

        Public Enum ItemLocation
            Inventory = 0
            EquipArmor = 1
            EquipWeapon = 2
            EquipHelmet = 3
            EquipNecklace = 4
            EquipLeftBracer = 5
            EquipLeftRing = 6
            EquipRightBracer = 7
            EquipRightRing = 8
            EquipShoes = 9
            EquipTalisman = 10
            EquipTorch = 11
            EquipTrinket = 12
            EquipHorseArmor = 13
            CommisionMerchant = 14
            Storage = 15
            Shop = 16
            Floor = 17

            Deleted = 255
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure FloorItem
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID As Int64
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_ITEMNAME_LEN)> Dim STR_NAME As String
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_ITEMCLASS As ItemClass
            <MarshalAs(UnmanagedType.I4)> Dim INT_LOOKS As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_COUNT As Integer
            <MarshalAs(UnmanagedType.I2)> Dim INT2_X As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_Y As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_WEIGHT As Int16
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure StatsSet
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MIN_AC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MIN_MAC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MIN_DC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MIN_MC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MIN_SC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_HP As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_MP As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_AC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_MAC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_DC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_MC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_SC As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_FIRE As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_ICE As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_LIGHT As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_WIND As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_HOLY As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_DARK As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMC_PHANTOM As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_FIRE As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_ICE As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_LIGHT As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_WIND As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_HOLY As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_DARK As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ELEMAC_PHANTOM As Int16
            <MarshalAs(UnmanagedType.U1)> Dim INT1_ACCURACY As Byte
            <MarshalAs(UnmanagedType.U1)> Dim INT1_AGILITY As Byte
            <MarshalAs(UnmanagedType.U1)> Dim INT1_VELOCITY As Byte
            <MarshalAs(UnmanagedType.I4)> Dim INT_MAX_DURABILITY As Integer
            <MarshalAs(UnmanagedType.U1)> Dim INT1_STRENGTH As Byte
            <MarshalAs(UnmanagedType.U1)> Dim INT1_LUCK As Byte
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_WEIGHT As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_HANDWEIGHT As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_MAX_WEARWEIGHT As Int16
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ItemBaseInfo
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID_ITEMBASE As Long
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_ITEMNAME_LEN)> Dim STR_NAME As String
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As ItemType
            <MarshalAs(UnmanagedType.I4)> Dim INT_SHAPE As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_LOOKS As Integer
            <MarshalAs(UnmanagedType.Bool)> Dim BOOL_STACKS As Boolean
            <MarshalAs(UnmanagedType.I8)> Dim INT8_COST As Long
            <MarshalAs(UnmanagedType.I4)> Dim INT_STDITEM As Integer
            <MarshalAs(UnmanagedType.I2)> Dim INT2_LEVELREQ As Int16
            <MarshalAs(UnmanagedType.I2)> Dim INT2_WEIGHT As Int16
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_ITEMCLASS As ItemClass
            <MarshalAs(UnmanagedType.U1)> Dim INT1_EXPBONUS As Byte
            Dim Stats As StatsSet
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ItemInfo
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID As Long
            Dim Base As ItemBaseInfo
            <MarshalAs(UnmanagedType.I4)> Dim INT_ALPHACOL As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_COUNT As Integer
            Dim AddedStats As StatsSet
            <MarshalAs(UnmanagedType.I2)> Dim INT2_ITEMLEVEL As Int16
            <MarshalAs(UnmanagedType.I4)> Dim INT_ITEMEXP As Integer
            <MarshalAs(UnmanagedType.I4)> Dim INT_DURABILITY As Integer
            <MarshalAs(UnmanagedType.I8)> Dim INT_REALCOST As Long
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ItemSlotInfo
            Dim item As ItemInfo
            Dim slot As ItemLocation
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ItemLocationInfo
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID As Int64
            Dim location As ItemLocation
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ItemUseRequest
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID As Int64
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure DropItemRequest
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID As Int64
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure SplitStackRequest
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID As Int64
            <MarshalAs(UnmanagedType.I4)> Dim INT_STACKSIZE As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure JoinStackRequest
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID_A As Int64
            <MarshalAs(UnmanagedType.I8)> Dim INT_ID_B As Int64
        End Structure

#End Region
#Region "=========  HUM ANIMATIONS  ========="

        Public Enum HUMAnimation As Byte
            Standing = 0
            Cast1 = 2
            Pushed = 3
            Pushing = 4
            Cast2 = 2
            Walking = 21
            Running = 22
            Attack = 9
            GettingHit = 15
            Die = 19
            MountedStand = 29
            MountedWalk = 30
            MountedRun = 31
        End Enum

        Public HUMAnimationCounts() As Integer = {4, 10, 5, 10, 10, 10, 10, 10, 10, 6, 10, 10, 10, 10, 10, 3, 10, 10, 10, 10, 10, 6, 6, 10, 10, 10, 10, 10, 10, 4, 6, 6, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}

        Public HUMAnimationDistanceX() As Single = {0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 6.0F, 6.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 12.0F, 12.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F}

        'Public HUMAnimationDistanceY() As Single = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6}
        Public HUMAnimationDistanceY() As Single = {0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 4.0F, 4.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 8.0F, 8.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F}

        Public HUMAnimationMoveTick() As Long = {2500000, 5000000, 2500000, 5000000, 5000000, 5000000, 5000000, 5000000, 5000000, 2500000, 5000000, 5000000, 5000000, 5000000, 5000000, 2500000, 5000000, 5000000, 5000000, 2500000, 5000000, 750000, 325000, 5000000, 5000000, 5000000, 5000000, 5000000, 5000000, 250000, 400000, 300000, 5000000, 5000000, 5000000, 5000000, 5000000, 5000000, 5000000, 5000000, 5000000, 0}

        Public HUMAnimationTick() As Long = {5000000, _
                                             5000000, _
                                             1300000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             750000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             1500000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             1500000, _
                                             5000000, _
                                             1000000, _
                                             750000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             500000, _
                                             700000, _
                                             700000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             5000000, _
                                             0}

#End Region
#Region "=========  CHAT  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ChatMsg
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHATMSG_LEN)> Dim STR_MSG As String
        End Structure

        Public Enum ChatMsgType As Byte
            Normal = 0
            LocalShout = 1
            GlobalShout = 2
            Whisper = 3
            SentWhisper = 4
            System = 5
            Admin = 6
            Server = 7
            Group = 8
            Guild = 9
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure CharChatMsg
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim STR_NAME As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim STR_TONAME As String
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As ChatMsgType
            Dim msg As ChatMsg
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure MobChatMsg
            <MarshalAs(UnmanagedType.I8)> Dim ServerMobID As Int64
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As ChatMsgType
            Dim M As ChatMsg
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure SayInfo
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_SAY_LEN)> Dim Text As String
        End Structure

#End Region


#Region "=========  GROUP  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure GroupName
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim Name As String
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure GroupNameID
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim Name As String
            <MarshalAs(UnmanagedType.I8)> Dim ID As Int64
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure GroupID
            <MarshalAs(UnmanagedType.I8)> Dim ID As Int64
        End Structure

#End Region

#Region "Skills"

        Public Enum Skills As Byte

            Fencing = 0
            Slaying = 1
            Healing = 2
            Spiritsword = 3
            Fireball = 4

        End Enum

        Public Enum SkillSet As Byte

            Set1 = 0
            Set2 = 1
            Set3 = 2
            Set4 = 3

            NotSet = 20

        End Enum

        Public Enum SkillKey As Byte

            F1 = 0
            F2 = 1
            F3 = 2
            F4 = 3
            F5 = 4
            F6 = 5
            F7 = 6
            F8 = 7
            F9 = 8
            F10 = 9
            F11 = 10
            F12 = 11

            NotSet = 20

        End Enum




        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerSkillDesc
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SKILL As Skills
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_LEVEL As Byte
            <MarshalAs(UnmanagedType.I8)> Dim INT_EXP As Int64
            <MarshalAs(UnmanagedType.I8)> Dim INT_LEVEL_EXP As Int64
        End Structure

        Public Structure PlayerSkillLevelStat
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_LEVEL As Byte
            <MarshalAs(UnmanagedType.I8)> Dim INT_EXP As Int64

        End Structure

        Public Structure PlayerSkill
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SKILL As Skills
            Dim LVL_1 As PlayerSkillLevelStat
            Dim LVL_2 As PlayerSkillLevelStat
            Dim LVL_3 As PlayerSkillLevelStat
            Dim LVL_4 As PlayerSkillLevelStat
            Dim LVL_5 As PlayerSkillLevelStat
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_SKILLDESC_LEN)> Dim STR_DESC As String
            Dim KEY_MAP As PlayerSkillMapping
            Dim LEVEL_INFO As PlayerSkillDesc
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerSkillMapping
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SKILL As Skills
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_SET As SkillSet
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_KEY As SkillKey
        End Structure

#End Region


#Region "=========  IMGLIBS  ========="

        Public Enum ImgLibs
            Interface1c = 0
            GameInter = 1
            EvoInterface = 2
            TileSC = 3
            TileS30C = 4
            HouseSC = 5
            CliffSC = 6
            SMObjectSC = 7
            MHum = 10
            MHumEx1 = 11
            MHumA = 12
            MHumAEx1 = 13
            WMHum = 14
            WMHumEx1 = 15
            WMHumA = 16
            WMHumAEx1 = 17
            MHair = 18
            MHairA = 19
            WMHair = 20
            WMHairA = 21
            MHelmet1 = 22
            MHelmet2 = 23
            MHelmetA1 = 24
            MHelmetA2 = 25
            WMHelmet1 = 26
            WMHelmet2 = 27
            WMHelmetA1 = 28
            WMHelmetA2 = 29
            MWeapon1 = 30
            MWeapon2 = 31
            MWeapon3 = 32
            MWeapon4 = 33
            MWeapon5 = 34
            MWeapon6 = 35
            MWeapon7 = 36
            MWeapon10 = 37
            MWeapon11 = 38
            MWeaponADL1 = 39
            MWeaponADR1 = 40
            MWeaponAOH1 = 41
            MWeaponAOH2 = 42
            WMWeapon1 = 43
            WMWeapon2 = 44
            WMWeapon3 = 45
            WMWeapon4 = 46
            WMWeapon5 = 47
            WMWeapon6 = 48
            WMWeapon7 = 49
            WMWeapon10 = 50
            WMWeapon11 = 51
            WMWeaponADL1 = 52
            WMWeaponADR1 = 53
            WMWeaponAOH1 = 54
            WMWeaponAOH2 = 55
            Inventory = 56
            ProgUse = 57
            Equip = 58
            MonImg = 59
            Magic = 60
            NPC = 61
            StoreItem = 62

            Objects1C = 67
            AnimationSC = 71
            Ground = 72
            Horse = 73
            HorseS = 74
            Fmmap = 75
            Tiles5C = 76

            SmTileSC = 77
            DungeonSC = 78
            InnerSC = 79
            FurnitureSC = 80
            WallSC = 81
            Object2C = 82
            DataCustom = 83

            WoodTiles30C = 84
            WoodTiles5C = 85
            WoodSMTilesSC = 86
            WoodDungeonSC = 87
            WoodInnerSC = 88
            WoodWallSC = 89
            WoodAnimationSC = 90
            WoodObject1C = 91
            WoodObject2C = 92
            WoodCustom = 93
            WoodTileSC = 68
            WoodHouseSC = 69
            WoodCliffSC = 70
            WoodFurnitureSC = 8
            WoodSMObjectSC = 9

            SandTiles30C = 94
            SandTiles5C = 95
            SandSMTileSC = 96
            SandDungeonSC = 97
            SandInnerSC = 98
            SandWallSC = 99
            SandAnimationSC = 100
            SandObject1C = 101
            SandObject2C = 102
            SandCustom = 103
            SandTileSC = 104
            SandHouseSC = 105
            SandCliffSC = 106
            SandFurnitureSC = 107
            SandSMObjectSC = 108

            SnowTiles30C = 109
            SnowTiles5C = 110
            SnowSMTilesC = 111
            SnowDungeonSC = 112
            SnowInnerSC = 113
            SnowWallSC = 114
            SnowAnimationSC = 115
            SnowObject1C = 116
            SnowObject2C = 117
            SnowCustom = 118
            SnowTileSC = 119
            SnowHouseSC = 120
            SnowCliffSC = 121
            SnowFurnitureSC = 122
            SnowSMObjectSC = 123

            ForestTiles30C = 124
            ForestTiles5C = 125
            ForestSMTileSC = 126
            ForestDungeonSC = 127
            ForestInnerSC = 128
            ForestWallSC = 129
            ForestAnimationSC = 130
            ForestObject1C = 131
            ForestObject2C = 132
            ForestCustom = 133
            ForestTileSC = 134
            ForestHouseSC = 135
            ForestCliffSC = 136
            ForestFurnitureSC = 137
            ForestSMObjectSC = 138

            GameInter1 = 139

            MIcon = 140


            Mon1 = 170
            MonS1 = 171
            Mon2 = 172
            MonS2 = 173
            Mon3 = 174
            MonS3 = 175

        End Enum

        'Tells the client at which # the Mon##/Mon##S libs begin
        Public Const StartOfMonLibs As Integer = 170

#End Region

#Region "=========  NPCS  ========="

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure NPCAddInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_MONNAME_LEN)> Dim Name As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_FUNC_LEN)> Dim CMD As String
            <MarshalAs(UnmanagedType.I4)> Dim Shape As Integer
            <MarshalAs(UnmanagedType.I4)> Dim X As Integer
            <MarshalAs(UnmanagedType.I4)> Dim Y As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure NPCChatMsg
            <MarshalAs(UnmanagedType.I8)> Dim ServerID As Int64
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As ChatMsgType
            Dim M As ChatMsg
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.Bool)> Dim BOOL_GRIDLIST As Boolean
        End Structure

        Public Enum ShopListType As Byte
            None = 0
            Sell = 1
            Repair = 2
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopListInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As ShopListType
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopAllowList
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_TYPE As ItemType
        End Structure

        Public Enum ShopDefType As Byte
            StackItem = 0
            GridItem = 1
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopItemInfo
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_DEFTYPE As ShopDefType
            Dim Info As ItemInfo
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopItemBuyInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_DEFTYPE As ShopDefType
            <MarshalAs(UnmanagedType.I8)> Dim ID As Int64
            <MarshalAs(UnmanagedType.I4)> Dim INT_COUNT As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure NPCCall
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_FUNC_LEN)> Dim CMD As String
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopLoadItemsInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.I8)> Dim ID_ITEMBASE As Int64
            <MarshalAs(UnmanagedType.I4)> Dim INT_PAGE As Integer
        End Structure

        Public Enum ShopSellType As Byte
            SellGetPrice = 0
            SellDoIt = 1
            RepairGetCost = 2
            RepairDoIt = 3
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ShopItemSellInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_NPC As Int64
            <MarshalAs(UnmanagedType.U1)> Dim BYTE_DEFTYPE As ShopSellType
            <MarshalAs(UnmanagedType.I8)> Dim ID As Int64
            <MarshalAs(UnmanagedType.I4)> Dim INT_COUNT As Integer
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure NPCShopSellPrice
            <MarshalAs(UnmanagedType.I8)> Dim ID As Int64
            <MarshalAs(UnmanagedType.I8)> Dim INT8_OFFER As Int64
        End Structure

#End Region




#Region "=========  INTERSERVER  ========="

        Public Enum InterServerPacketType As Byte

            ServerOnline = 1

            RefreshStat = 2

            UserLogin = 3
            UserLogout = 4

            XServerChatMessage = 10

        End Enum

        Public Const MAX_STAT_LEN As Integer = 64

        Public Enum ServerStat As Byte
            Uptime = 0
            ServerFPS = 1
            UserCount = 2
            MaintainanceMode = 3
        End Enum

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure ServerHost
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_HOSTNAME_LEN)> Dim STR_HOSTNAME As String
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure RefreshStat
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_HOSTNAME_LEN)> Dim STR_HOSTNAME As String
            <MarshalAs(UnmanagedType.U1)> Dim ID_STAT As ServerStat
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_STAT_LEN)> Dim STR_VALUE As String
            <MarshalAs(UnmanagedType.I8)> Dim INT_VALUE As Int64
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Public Structure PlayerOnlineInfo
            <MarshalAs(UnmanagedType.I8)> Dim ID_CHARACTER As Int64
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_CHARNAME_LEN)> Dim STR_NAME As String
        End Structure


#End Region




#Region "=========  FUNCTIONS  ========="

        Public Enum ParsePacketCode
            OK = 0
            Incomplete = 1
            PacketError = 2
            NoData = 3
            DecryptError = 4
        End Enum

        Public Function MakePacket(ByRef info As Packet, Optional ByRef payload As Object = Nothing, _
                                                 Optional ByVal crypt As Cryptography.Crypto = Nothing) As Byte()

            Dim payloadlen As UInt16 = 0
            Dim bPayload() As Byte
            Dim bEncryptedPayload() As Byte = Nothing

            If Not payload Is Nothing Then

                bPayload = Functions.StructToArray(payload, payload.GetType())





                'ENCRYPT CODE

                'Select info.CryptoType

                'Case CryptoType.DefaultCrypto
                'bEncryptedPayload = Cryptography.Cryptography.DefaultCrypto.EncryptBytes(bPayload)

                '    Case CryptoType.UsernameCrypto
                If crypt Is Nothing Then
                    bEncryptedPayload = DefaultCrypto.EncryptBytes(bPayload)
                    'Throw New ArgumentException("crypt must contain a valid Encryption.Crypto object when info.CryptoType is CryptoType.UsernameCrypto")
                Else
                    bEncryptedPayload = crypt.EncryptBytes(bPayload)
                End If

                'Case Else
                'Throw New ArgumentException("info.CryptoType is invalid")

                'End Select

                '''''''''''/



                'IGNORE ENCRYPTION CODE 

                'bEncryptedPayload = bPayload

                '''''''''''/



                payloadlen = bEncryptedPayload.Length

            End If

            Dim raw As New RawPacket
            Dim bBytes(Marshal.SizeOf(raw) + payloadlen) As Byte

            raw.Proto = bProto
            raw.StartHeaderByte = bProtoStartHeader
            raw.HeaderUsername = ProtoHeaders.Username
            raw.Username = info.Username
            raw.HeaderPacketType = ProtoHeaders.PacketType
            raw.PacketType.UINT16_TYPE = info.PacketType
            raw.HeaderPacketOpCode = ProtoHeaders.PacketOpCode
            raw.PacketOpCode = info.PacketOpCode
            raw.HeaderPayload = ProtoHeaders.Payload
            raw.PayloadLength = payloadlen

            Functions.StructToArray(raw, GetType(RawPacket)).CopyTo(bBytes, 0) 'payload length

            If Not payload Is Nothing Then
                bEncryptedPayload.CopyTo(bBytes, Marshal.SizeOf(raw)) 'encrypted payload bytes
            End If

            bBytes(Marshal.SizeOf(raw) + payloadlen) = ProtoHeaders.EndOfTransmission 'EOT to mark end of packet

            Return bBytes

        End Function

        Public Function ParsePacket(ByRef bData() As Byte, ByRef info As Packet, ByRef bStruct() As Byte, _
        Optional ByRef crypt As Cryptography.Crypto = Nothing) As ParsePacketCode

            If bData Is Nothing Then
                Return ParsePacketCode.NoData
            End If

            If bData.Length < 4 Then
                Return ParsePacketCode.NoData
            End If

            If bData(0) = 0 And bData(1) = 0 And bData(2) = 0 And bData(3) = 0 Then
                Return ParsePacketCode.NoData
            End If

            Dim raw As New RawPacket

            If bData.Length < Marshal.SizeOf(raw) Then Return ParsePacketCode.Incomplete

            Dim bRawPacket(Marshal.SizeOf(raw) - 1) As Byte

            Array.Copy(bData, bRawPacket, Marshal.SizeOf(raw))

            Try

                raw = Functions.ArrayToStruct(bRawPacket, GetType(RawPacket))

            Catch ex As System.StackOverflowException

                'Find next occourance of the Protocol Header

                For i As Integer = 4 To bData.Length - 4

                    If bData(i) = bProto(3) Then
                        If bData(i + 1) = bProto(2) Then
                            If bData(i + 2) = bProto(1) Then
                                If bData(i + 3) = bProto(0) Then

                                    Dim bGoodData(bData.Length - i) As Byte
                                    Array.Copy(bData, i, bGoodData, 0, bData.Length - i)
                                    bData = bGoodData
                                    Return ParsePacketCode.PacketError

                                End If
                            End If
                        End If
                    End If

                Next

                bData = Nothing
                Return ParsePacketCode.PacketError

            End Try

            Dim iPacketSize = raw.PayloadLength + Marshal.SizeOf(raw) + 1

            If iPacketSize > bData.Length Then
                Return ParsePacketCode.Incomplete
            Else

                If ASCII.GetString(raw.Proto, 0, bProto.Length) = sProto And _
                    raw.StartHeaderByte = bProtoStartHeader And _
                    raw.HeaderUsername = ProtoHeaders.Username And _
                    raw.HeaderPacketType = ProtoHeaders.PacketType And _
                    raw.HeaderPacketOpCode = ProtoHeaders.PacketOpCode And _
                    raw.HeaderPayload = ProtoHeaders.Payload And _
                    bData(Marshal.SizeOf(raw) + raw.PayloadLength) = ProtoHeaders.EndOfTransmission Then

                    If raw.PayloadLength > 0 Then

                        Dim bEncrypted(raw.PayloadLength - 1) As Byte
                        Array.Copy(bData, Marshal.SizeOf(raw), bEncrypted, 0, raw.PayloadLength)


                        'DECRYPT CODE

                        'If raw.CryptoType = CryptoType.DefaultCrypto Then

                        'bStruct = Cryptography.Cryptography.DefaultCrypto.DecryptBytes(bEncrypted)

                        'ElseIf raw.CryptoType = CryptoType.UsernameCrypto Then

                        Try
                            If crypt Is Nothing Then
                                bStruct = DefaultCrypto.DecryptBytes(bEncrypted)
                            Else
                                bStruct = crypt.DecryptBytes(bEncrypted)
                            End If

                        Catch ex As Exception

                            If bData.Length > iPacketSize Then

                                Dim bExcess(bData.Length - iPacketSize - 1) As Byte
                                Array.Copy(bData, iPacketSize, bExcess, 0, bData.Length - iPacketSize)
                                bData = bExcess
                            Else
                                bData = Nothing
                            End If

                            Return ParsePacketCode.DecryptError

                        End Try

                        'Else
                        'Return ParsePacketCode.PacketError
                        'End If


                        '''''''''''/



                        'IGNORE DECRYPT CODE

                        'If raw.PayloadLength = bEncrypted.Length Then

                        'bStruct = bEncrypted

                        'Else

                        'If bData.Length > iPacketSize Then

                        ' Dim bExcess(bData.Length - iPacketSize - 1) As Byte
                        '  Array.Copy(bData, iPacketSize, bExcess, 0, bData.Length - iPacketSize)
                        '   bData = bExcess
                        'Else
                        '   bData = Nothing
                        'End If

                        'Return ParsePacketCode.PacketError

                        'End If

                        '''''''''''/

                    Else
                        bStruct = Nothing
                    End If

                    If bData.Length > iPacketSize Then
                        Dim bExcess(bData.Length - iPacketSize - 1) As Byte
                        Array.Copy(bData, iPacketSize, bExcess, 0, bData.Length - iPacketSize)
                        bData = bExcess
                    Else
                        bData = Nothing
                    End If

                    'Array.Copy(info.Username, raw.Username, DefaultUsername.Length)
                    info.Username = raw.Username
                    info.PacketType = raw.PacketType.UINT16_TYPE
                    info.PacketOpCode = raw.PacketOpCode

                    Return ParsePacketCode.OK

                Else

                    Return ParsePacketCode.PacketError

                End If

            End If

        End Function

#End Region



    End Module

End Namespace